import tkinter as tk
from tkinter import filedialog, messagebox
import pypandoc
import pyperclip
from docx import Document
from docx.oxml.ns import qn
import os
from datetime import datetime
import tempfile
import shutil

# --------------------- 核心功能优化 ---------------------
def set_song_font(doc):
    """统一设置文档字体为宋体（优化版）"""
    styles = doc.styles
    font_name = 'SimSun'
    
    # 设置全局默认样式
    styles['Normal'].font.name = font_name
    styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)
    
    # 设置标题样式
    for level in range(1, 6):
        style_name = f'Heading {level}'
        if style_name in styles:
            styles[style_name].font.name = font_name
            styles[style_name]._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)

def convert_autonumbering_to_text(paragraph):
    """将自动编号或符号转换为普通文本并保留"""
    pPr = paragraph._element.get_or_add_pPr()
    numPr = pPr.find(qn("w:numPr"))
    
    # 检查numPr是否存在
    if numPr is not None:
        abstractNumId_elem = numPr.find(qn("w:abstractNumId"))
        ilvl_elem = numPr.find(qn("w:ilvl"))
        
        # 确保所需元素都存在
        if abstractNumId_elem is not None and ilvl_elem is not None:
            abstractNumId = abstractNumId_elem.get("{http://schemas.openxmlformats.org/officeDocument/2006/main}val")
            ilvl = ilvl_elem.get("{http://schemas.openxmlformats.org/officeDocument/2006/main}val")
            
            # 假设我们用一个简单的数字代替实际编号，这需要根据具体情况调整
            number = f"{int(ilvl)+1}. "  # 示例：简单地在每级上加1
            
            # 在段落开头添加编号文本
            run = paragraph.add_run(number)
            run.font.name = 'SimSun'
            run._element.rPr.rFonts.set(qn('w:eastAsia'), 'SimSun')
            
            # 移除原有的numPr属性
            pPr.remove(numPr)
        else:
            print("缺少必要的编号属性")
    else:
        print("段落没有自动编号或符号")

def process_docx_autonumbering(doc):
    """处理整个文档的自动编号问题（优化版），保留原始文本内容及编号"""
    for paragraph in doc.paragraphs:
        convert_autonumbering_to_text(paragraph)
        
    # 处理表格中的自动编号
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    convert_autonumbering_to_text(paragraph)

# --------------------- 文件操作优化 ---------------------
def safe_convert_md_to_docx(md_file, docx_file):
    """安全的Markdown转Word转换（包含错误处理）"""
    try:
        # 添加Markdown扩展支持
        pypandoc.convert_file(
            md_file, 
            'docx', 
            outputfile=docx_file,
            format='markdown+hard_line_breaks',
            extra_args=['--wrap=preserve']
        )
        
        # 设置文档字体并处理自动编号
        doc = Document(docx_file)
        set_song_font(doc)
        process_docx_autonumbering(doc)
        doc.save(docx_file)
        
    except Exception as e:
        raise RuntimeError(f"转换失败: {str(e)}")

def merge_documents(target_path, source_path):
    """合并两个Word文档（优化内容追加）"""
    target_doc = Document(target_path)
    source_doc = Document(source_path)
    
    # 添加分页符
    target_doc.add_page_break()
    
    # 复制所有元素（段落、表格等）
    for element in source_doc.element.body:
        target_doc.element.body.append(element)
    
    # 处理格式
    process_docx_autonumbering(target_doc)
    set_song_font(target_doc)
    target_doc.save(target_path)

# --------------------- GUI逻辑优化 ---------------------
class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("AI输出文本转Word工具V1.0")
        self.output_path = None
        self.temp_dir = tempfile.TemporaryDirectory()
        self.geometry("400x240")  # 调整窗口大小
        
        self.create_widgets()
        self.protocol("WM_DELETE_WINDOW", self.on_close)
        
    def create_widgets(self):
        # 增加顶部框架用于文件选择组件
        top_frame = tk.Frame(self)
        top_frame.pack(pady=10, fill=tk.X)
        
        self.file_btn = tk.Button(top_frame, text="选择目标文件", command=self.select_file)
        self.file_btn.pack(side=tk.LEFT, padx=10)
        
        self.file_label = tk.Label(top_frame, text="当前操作文件: 未选择", wraplength=250)
        self.file_label.pack(side=tk.LEFT)
        
        # 操作按钮区域
        btn_frame = tk.Frame(self)
        btn_frame.pack(pady=20)
        
        self.save_btn = tk.Button(btn_frame, text="覆盖保存", command=self.save_overwrite, width=15)
        self.save_btn.pack(side=tk.LEFT, padx=15)
        
        self.append_btn = tk.Button(btn_frame, text="追加保存", command=self.save_append, width=15)
        self.append_btn.pack(side=tk.RIGHT, padx=15)
        
        # 状态栏
        self.status_bar = tk.Label(self, text="就绪", bd=1, relief=tk.SUNKEN, anchor=tk.W)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
    
    def update_status(self, message):
        self.status_bar.config(text=message)
        self.update_idletasks()
    
    def select_file(self):
        path = filedialog.asksaveasfilename(
            defaultextension=".docx",
            filetypes=[("Word文档", "*.docx"), ("所有文件", "*.*")]
        )
        if path:
            self.output_path = path
            self.file_label.config(text=f"当前操作文件: {os.path.basename(path)}")
            
    def validate_operation(self):
        """验证操作前置条件"""
        content = pyperclip.paste().strip()
        if not content:
            messagebox.showerror("错误", "剪贴板为空，请先复制AI生成的内容")
            return False
            
        if not self.output_path:
            self.output_path = self.generate_default_filename()
            self.file_label.config(text=f"自动生成文件: {os.path.basename(self.output_path)}")
            messagebox.showinfo("提示", f"已自动生成文件: {self.output_path}")
            
        return True
    
    def generate_default_filename(self):
        """生成默认文件名"""
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        return os.path.join(os.getcwd(), f"AI_Output_{timestamp}.docx")
    
    def save_overwrite(self):
        if not self.validate_operation():
            return
            
        try:
            self.update_status("正在处理覆盖保存...")
            with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False, encoding="utf-8") as md_temp:
                md_temp.write(pyperclip.paste())
                md_path = md_temp.name
                
            docx_temp = os.path.join(self.temp_dir.name, "temp.docx")
            safe_convert_md_to_docx(md_path, docx_temp)
            
            shutil.move(docx_temp, self.output_path)
            self.update_status(f"成功覆盖保存到: {self.output_path}")
            
        except Exception as e:
            messagebox.showerror("错误", f"保存失败: {str(e)}")
        finally:
            if os.path.exists(md_path):
                os.remove(md_path)
    
    def save_append(self):
        if not self.validate_operation():
            return
            
        try:
            self.update_status("正在处理追加保存...")
            # 生成临时文件路径
            md_temp = os.path.join(self.temp_dir.name, "append_temp.md")
            docx_temp = os.path.join(self.temp_dir.name, "append_temp.docx")
            
            with open(md_temp, "w", encoding="utf-8") as f:
                f.write(pyperclip.paste())
                
            safe_convert_md_to_docx(md_temp, docx_temp)
            
            if os.path.exists(self.output_path):
                merge_documents(self.output_path, docx_temp)
            else:
                shutil.copy(docx_temp, self.output_path)
                
            self.update_status(f"成功追加内容到: {self.output_path}")
            
        except Exception as e:
            messagebox.showerror("错误", f"追加失败: {str(e)}")
    
    def on_close(self):
        """清理临时资源"""
        try:
            self.temp_dir.cleanup()
        except:
            pass
        self.destroy()

if __name__ == "__main__":
    app = Application()
    app.mainloop()
